package main

import (
	"fmt"
	"flag"
	"os"
	"sync"
	"bytes"
	"io"
)

var lock bool

func init() {
	flag.BoolVar(&lock, "lock", false, "是否加锁")
}

const (
	max1 = 5   // 准备启用多个goroutine
	max2 = 10  // 每个goroutine里写入这么多组数据
	max3 = 10  // 每组数据就是重复写入多个数字
)

func main () {
	// 解析命令行参数
	flag.Parse()

	// bytes.Buffer是一个缓冲byte类型的缓冲器，存放的都是byte类型
	var buffer bytes.Buffer
	var mu sync.Mutex  // 互斥锁
	done := make(chan struct{})  // 每当一个goroutine执行完毕了，就往这里发一个信号
	
	for i := 0; i < max1; i++ {
		go func(id int, writer io.Writer) {
			defer func() {
				done <- struct{}{}
			}()
			for j := 0; j < max2; j++ {
				// 准备数据
				header := fmt.Sprintf("\n[%d %d]", id, j)
				data := fmt.Sprintf(" %d-%d", id, j)
				// 加锁
				if lock {
					mu.Lock()
				}
				// 写入数据
				_, err := writer.Write([]byte(header))
				if err != nil {
					fmt.Fprintf(os.Stderr, "ERROR when write header in %d: %s\n", id, err)
				}
				for k := 0; k < max3; k++ {
					_, err := writer.Write([]byte(data))
					if err != nil {
						fmt.Fprintf(os.Stderr, "ERROR when write data in %d: %s\n", id, err)
					}
				}
				// 解锁
				if lock {
					mu.Unlock()
				}
			}
		}(i, &buffer)
	}
	// 等待goroutine退出
	for i := 0; i < max1; i++ {
		<- done
	}
	// 打印结果
	fmt.Println(buffer.String())
}